package com.zhuoyue.web.controller;


import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.zhuoyue.biz.core.api.dao.AppUserDao;
import com.zhuoyue.biz.core.api.domain.AppUserDO;
import com.zhuoyue.biz.core.api.service.AppUserService;
import com.zhuoyue.common.dto.ControllerResult;
import com.zhuoyue.common.jwt.util.JwtOperator;
import io.jsonwebtoken.Claims;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.zhuoyue.common.constant.RequestType.MANAGE;

/**
 * 第三方请求
 * <p>
 * 不能删除，其他服务需要调用
 *
 * @author wjming
 */
@RestController
@RequestMapping("/smart/home/user")
@Validated
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ThirdPartyUerController {
    private final AppUserService appUserService;

    private final AppUserDao appUserDao;

    private final JwtOperator jwtOperator;

    @PostMapping("/get/token")
    public ControllerResult<AppUserDO> getToken(String account, String password, @RequestHeader String organizationCode,
                                                @NotBlank(message = "业务类型不能为空") String type) throws Exception {
        AppUserDO appUserDO = new AppUserDO();
        appUserDO.setAccount(account);
        appUserDO.setPassword(password);
        appUserDO.setOrganizationCode(organizationCode);
        AppUserDO appUser = new AppUserDO();
        //生成用户token信息
        Map<String, Object> claims = new HashMap<>(6);
        //如果是来自后台管理系统的请求，则不进行用户校验，因为用户信息非同库
        if (!MANAGE.equals(type)) {
            appUser = appUserService.getAppUserByAccountAndPassword(appUserDO);
            if (appUser == null) {
                return ControllerResult.toNoDataFail("用户名或密码错误");
            }
            claims.put("id", appUser.getId());
            claims.put("account", appUser.getAccount());
        } else {
            claims.put("account", account);
        }

        claims.put("orgCode", organizationCode);
        claims.put("type", type);
        String token = jwtOperator.generateToken(claims);
        return ControllerResult.toReturnDataSuccess("验证成功", token);
    }

    @GetMapping("/third/get/token")
    public ControllerResult<AppUserDO> thirdGetToken(String account, String password, @NotBlank String organizationCode,
                                                     @NotBlank(message = "业务类型不能为空") String type) throws Exception {
        AppUserDO appUserDO = new AppUserDO();
        appUserDO.setAccount(account);
        appUserDO.setPassword(password);
        appUserDO.setOrganizationCode(organizationCode);
        AppUserDO appUser = appUser = appUserService.getAppUserByAccountAndPassword(appUserDO);
        if (appUser == null) {
            return ControllerResult.toNoDataFail("用户名或密码错误");
        }
        Map<String, Object> claims = new HashMap<>(6);
        claims.put("id", appUser.getId());
        claims.put("account", appUser.getAccount());
        claims.put("orgCode", organizationCode);
        claims.put("type", type);
        String token = jwtOperator.generateTokenCustomTime(claims, 31536000L);

        Date expirationDateFromToken = jwtOperator.getExpirationDateFromToken(token);
        return ControllerResult.toReturnDataSuccess("验证成功", new RepThirdAuthMessage(token, expirationDateFromToken));
    }

    /**
     * 刷新token
     *
     * @param account
     * @param organizationCode
     * @param type
     * @return
     * @throws Exception
     */
    @PostMapping("/refresh/token")
    public ControllerResult<AppUserDO> refreshToken(@NotBlank(message = "账号不能为空") String account,
                                                    @NotBlank(message = "组织编码不能为空") @RequestHeader
                                                            String organizationCode, String type) throws Exception {
        AppUserDO appUserDO = new AppUserDO();
        appUserDO.setAccount(account);
        appUserDO.setOrganizationCode(organizationCode);
        AppUserDO appUser = appUserDao.selectOne(Wrappers.<AppUserDO>lambdaQuery().eq(AppUserDO::getAccount, account)
                .eq(AppUserDO::getOrganizationCode, organizationCode));
        //生成用户token信息
        Map<String, Object> claims = new HashMap<>(6);
        claims.put("id", appUser.getId());
        claims.put("account", appUser.getAccount());
        claims.put("orgCode", organizationCode);
        claims.put("type", type);
        String token = jwtOperator.generateToken(claims);
        return ControllerResult.toReturnDataSuccess("验证成功", token);
    }

    /**
     * token验证
     *
     * @param token
     * @return
     * @throws Exception
     */
    @PostMapping("/authorize/token")
    public ControllerResult<AppUserDO> authorizeToken(@NotBlank(message = "token不能为空") @RequestHeader String token) throws Exception {
        Boolean aBoolean = jwtOperator.validateToken(token);
        if (aBoolean) {
            Map<String, Object> userMsg = new HashMap(3);
            Claims claimsFromToken = jwtOperator.getClaimsFromToken(token);
            userMsg.put("id", claimsFromToken.get("id").toString());
            userMsg.put("account", claimsFromToken.get("account").toString());
            userMsg.put("orgCode", claimsFromToken.get("orgCode").toString());
            return ControllerResult.toReturnDataSuccess("验证成功", userMsg);
        } else {
            return ControllerResult.toTokenExpiret("token验证失败");
        }
    }
}

/**
 * 回应第三方授权信息
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
class RepThirdAuthMessage {
    /**
     * 授权token
     */
    private String token;
    /**
     * 过期时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date expirationTime;

}
